#include "comm/my_log.h"
#include "comm/my_mem.h"
#include "comm/my_chash.h"

void test1()
{
    my_chash_t chash;
    my_chash_init(&chash, 100);

    my_str_t s1 = {.data="aaa", .len = 3};
    my_str_t s2 = {.data="bbb", .len = 3};
    my_str_t s3 = {.data="ccc", .len = 3};
    my_str_t s4 = {.data="ddd", .len = 3};
    my_str_t s5 = {.data="eee", .len = 3};

    my_chash_add_node(&chash, &s1, "aaa", 1);
    my_chash_add_node(&chash, &s2, "bbb", 1);
    my_chash_add_node(&chash, &s3, "ccc", 1);
    my_chash_add_node(&chash, &s4, "ddd", 1);
    my_chash_add_node(&chash, &s5, "eee", 1);
    my_chash_build(&chash);

    char buf[64];
    for (int i = 0; i < 1000; i++) {
        sprintf(buf, "%d", i);
        my_str_t key = {.data=buf, .len=(int64_t)strlen(buf)};
        void *data = my_chash_get(&chash, &key, NULL);
        if (data == NULL) {
            MY_LOG_FATAL("unexcept result");
        }
        MY_LOG_DEBUG("key: %d, data: %s", i, (char *)data);
    }

    my_chash_release(&chash);
}

my_bool_t my_chash_node_check(my_chash_node_t *node)
{
    if (node->key.len == 3
        && strncmp(node->key.data, "aaa", 3) == 0) {
        return MY_FALSE;
    }

    return MY_TRUE;
}

void test2()
{
    my_chash_t chash;
    my_chash_init(&chash, 100);

    my_str_t s1 = {.data="aaa", .len = 3};
    my_str_t s2 = {.data="bbb", .len = 3};
    my_str_t s3 = {.data="ccc", .len = 3};
    my_str_t s4 = {.data="ddd", .len = 3};
    my_str_t s5 = {.data="eee", .len = 3};

    my_chash_add_node(&chash, &s1, "aaa", 1);
    my_chash_add_node(&chash, &s2, "bbb", 1);
    my_chash_add_node(&chash, &s3, "ccc", 1);
    my_chash_add_node(&chash, &s4, "ddd", 1);
    my_chash_add_node(&chash, &s5, "eee", 1);
    my_chash_build(&chash);

    char buf[64];
    for (int i = 0; i < 1000; i++) {
        sprintf(buf, "%d", i);
        my_str_t key = {.data=buf, .len=(int64_t)strlen(buf)};
        void *data = my_chash_get(&chash, &key, my_chash_node_check);
        if (data == NULL) {
            continue;
        }

        if (strncmp(data, "aaa", 3) == 0) {
            MY_LOG_FATAL("unexcept result");
        }

        MY_LOG_DEBUG("key: %d, data: %s", i, (char *)data);
    }

    my_chash_release(&chash);
}

void test3()
{
    my_chash_t chash;
    my_chash_init(&chash, 100);

    my_chash_build(&chash);
    my_str_t key = {.data="aaa", .len = 3};
    void *data = my_chash_get(&chash, &key, NULL);
    if (data != NULL) {
        MY_LOG_FATAL("unexcept result");
    }

    my_chash_release(&chash);
}

int main()
{
    test1();

    test2();

    test3();

    my_mem_assert_leak();

    MY_LOG_DEBUG("test pass");
    return 0;
}